package com.chris.libs.devtools.x.v1.utils;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;

import com.google.gson.Gson;
import com.google.gson.reflect.TypeToken;

import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

/**
 * create by Chris Chan
 * create on 2019/7/9 23:24
 * use for :
 */
public class JsonUtils {
    private final static Gson gson = new Gson().newBuilder().create();

    /**
     * object转换为json字符串
     *
     * @param object
     * @return
     */
    public static String objToJson(Object object) {
        return gson.toJson(object);
    }

    /**
     * json字符串解析为object
     *
     * @param jsonStr
     * @param clazz
     * @param <T>
     * @return
     */
    public static <T> T jsonToObj(String jsonStr, Class<T> clazz) {
        try {
            return gson.fromJson(jsonStr, clazz);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

    /**
     * json字符串解析为List
     *
     * @param jsonStr
     * @param <T>
     * @return
     */
    @Deprecated
    public static <T> List<T> jsonToList(String jsonStr) {
        Type type = new TypeToken<List<T>>() {
        }.getType();
        return jsonToListByType(jsonStr, type);
    }

    /**
     * json字符串解析为List
     *
     * @param jsonStr
     * @param clazz
     * @param <T>
     * @return
     */
    public static <T> List<T> jsonToList(String jsonStr, Class<T> clazz) {
        if (StringUtil.isEmpty(jsonStr)) {
            return Collections.emptyList();
        }
        Type type = ListParameterizedType.create(clazz);
        return jsonToListByType(jsonStr, type);
    }

    /**
     * json字符串解析为List
     * 需要自己构建type
     *
     * @param jsonStr
     * @param type
     * @param <T>
     * @return
     */
    public static <T> List<T> jsonToListByType(String jsonStr, Type type) {
        return new Gson().newBuilder().create().fromJson(jsonStr, type);
    }

    /**
     * 处理ArrayList泛型参数被擦除的问题
     */
    private static class ListParameterizedType implements ParameterizedType {
        private Type type;

        public ListParameterizedType(Type type) {
            this.type = type;
        }

        public static ListParameterizedType create(Type type) {
            return new ListParameterizedType(type);
        }

        @NonNull
        @Override
        public Type[] getActualTypeArguments() {
            return new Type[]{type};
        }

        @NonNull
        @Override
        public Type getRawType() {
            return ArrayList.class;
        }

        @Nullable
        @Override
        public Type getOwnerType() {
            return null;
        }
    }
}

